// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_render_step_scene_render.h"
#include "mk_render_frame.h"
#include "mk_render_device.h"
#include "mk_engine.h"
#include "mk_render_step_view_culling.h"
#include "mk_error.h"
#include "mk_post_processor_manager.h"
#include "mk_render_step_refraction.h"
#include "mk_entity_water.h"
#include "mk_render_target.h"

#include "mk_scene.h"
#include "mk_shadow_TSM.h"
#include "mk_render_step_shadow_map.h"
#include "mk_painter.h"

namespace MK3DE
{
	const char* CRenderStepSceneRender::RenderStepName = "__RenderStepSceneRender";

	CRenderStepSceneRender::CRenderStepSceneRender(CRenderFrame* renderFrame)
		: CRenderStep(renderFrame, CRenderStepSceneRender::RenderStepName)
	{
		_bClearBk = TRUE;
		_bClearDepth = TRUE;
		_bClearStencil = TRUE;
		_bkColor = 0xff808080;
		_fDepth = 1.0f;
		_stencil = 0;
	}

	CRenderStepSceneRender::~CRenderStepSceneRender()
	{

	}

	void CRenderStepSceneRender::SetClearParam(BOOL bClearBk, BOOL bClearDepth, BOOL bClearStencil, DWORD bkColor, float fDepth, DWORD stencil)
	{
		_bClearBk = bClearBk;
		_bClearDepth = bClearDepth;
		_bClearStencil = bClearStencil;
		_bkColor = bkColor;
		_fDepth = fDepth;
		_stencil = stencil;
	}

	void CRenderStepSceneRender::Render()
	{
		CEngine* engine = GetEngine();
		CRenderDevice* renderDevice = engine->GetRenderDevice();
		CPostProcessorManager* postProcessManager = engine->GetPostProcessorManager();
		CRenderStepRefraction* rsRefraction = (CRenderStepRefraction*)_renderFrame->GetRenderStepByName(CRenderStepRefraction::RenderStepName);
		BOOL ret = FALSE;

		CRenderStepViewCulling* rsViewCulling = (CRenderStepViewCulling*)_renderFrame->GetRenderStepByName(CRenderStepViewCulling::RenderStepName);
		MK_PROCESS_ERROR(rsViewCulling);

		if (postProcessManager->IsEnable())
			postProcessManager->BeginFrame();
		else
			renderDevice->SetRenderTarget(NULL);

		ret = renderDevice->Clear(_bClearBk, _bClearDepth, _bClearStencil, _bkColor, _fDepth, _stencil);
		MK_PROCESS_ERROR(ret);

		for (int i = 0; i < (int)ERT_MAX; ++i)
		{
			CCullingProcessor::CullingResult& cullingResult = rsViewCulling->GetCullingResult();
			std::vector<CEntity*>& vecEntity = cullingResult.vecEntity[i];
			std::vector<CEntity*>::iterator it = vecEntity.begin();
			while (it != vecEntity.end())
			{
				CEntity* entity = *it;
				if (entity->GetType() == ET_WATER)
				{
					((CEntityWater*)entity)->SetRefractionTexture(rsRefraction->GetRefractionTarget()->GetRenderTargetTexture());
				}

				entity->Render();

				++it;
			}
		}

		if (postProcessManager->IsEnable())
			postProcessManager->EndFrame();

		/*
		CPainter* painter = engine->GetPainter();
		CRenderStepShadow* rsShadow = (CRenderStepShadow*)_renderFrame->GetRenderStepByName(CRenderStepShadow::RenderStepName);
		CTexture2D* pTexture = rsShadow->GetShadowMap()->GetRenderTargetTexture();
		painter->DrawImage2D(Rect2D(0, 0, 256, 256), RectColor(), pTexture);
		painter->Flush();

		CShadowTSM* tsm = rsViewCulling->GetScene()->GetShadowMapCalculator();
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[0].x, tsm->_frustum[0].y), D3DXVECTOR2(tsm->_frustum[4].x, tsm->_frustum[4].y), 0xff000000, 0xff0000ff);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[1].x, tsm->_frustum[1].y), D3DXVECTOR2(tsm->_frustum[5].x, tsm->_frustum[5].y), 0xff000000, 0xff0000ff);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[2].x, tsm->_frustum[2].y), D3DXVECTOR2(tsm->_frustum[6].x, tsm->_frustum[6].y), 0xff000000, 0xff0000ff);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[3].x, tsm->_frustum[3].y), D3DXVECTOR2(tsm->_frustum[7].x, tsm->_frustum[7].y), 0xff000000, 0xff0000ff);

		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[0].x, tsm->_frustum[0].y), D3DXVECTOR2(tsm->_frustum[1].x, tsm->_frustum[1].y), 0xff000000, 0xff000000);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[1].x, tsm->_frustum[1].y), D3DXVECTOR2(tsm->_frustum[2].x, tsm->_frustum[2].y), 0xff000000, 0xff000000);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[2].x, tsm->_frustum[2].y), D3DXVECTOR2(tsm->_frustum[3].x, tsm->_frustum[3].y), 0xff000000, 0xff000000);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[3].x, tsm->_frustum[3].y), D3DXVECTOR2(tsm->_frustum[0].x, tsm->_frustum[0].y), 0xff000000, 0xff000000);

		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[4].x, tsm->_frustum[4].y), D3DXVECTOR2(tsm->_frustum[5].x, tsm->_frustum[5].y), 0xff0000ff, 0xff0000ff);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[5].x, tsm->_frustum[5].y), D3DXVECTOR2(tsm->_frustum[6].x, tsm->_frustum[6].y), 0xff0000ff, 0xff0000ff);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[6].x, tsm->_frustum[6].y), D3DXVECTOR2(tsm->_frustum[7].x, tsm->_frustum[7].y), 0xff0000ff, 0xff0000ff);
		painter->DrawLine2D(D3DXVECTOR2(tsm->_frustum[7].x, tsm->_frustum[7].y), D3DXVECTOR2(tsm->_frustum[4].x, tsm->_frustum[4].y), 0xff0000ff, 0xff0000ff);

		painter->DrawRect(Rect2D(0, 0, 256, 256), RectColor());
		painter->Flush();
		*/

Exit0:
		return;
	}
}